package com.fruit.auth.dao.impl;



import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.jdbc.Work;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import com.fruit.auth.dao.UserDao;
import com.fruit.auth.dao.UserRoleDao;
import com.fruit.auth.model.User;
import com.fruit.dao.impl.BaseDaoImpl;

@Repository("userDao")
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao
{
	@Resource
	private UserRoleDao userRoleDao;
	public User login(String username)
	{
		return (User) findUniqueResultByHql("select new User(id,username,password,nickname) from User where username=?", username);
	}
	
	public boolean checkUsernameIsExists(String username)
	{
		long count= (long) findUniqueResultByHql("select count(*) from User where username=?", username);
		return count==0?true:false;
	}
	
	public void deleteUser(User user)
	{
		userRoleDao.unAuthUserRoles(user);
		batchEntityByHql("delete from User where id=?", user.getId());
	}
	
	public void deleteUsers(String userIdsStr)
	{
		userRoleDao.unAuthUsersRoles(userIdsStr);
		StringBuilder deleteUsersSql=new StringBuilder();
		deleteUsersSql.append("delete from AUTH_USER where id in(");
		deleteUsersSql.append(userIdsStr).append(")");
		executeUpdateSql(deleteUsersSql.toString());
	}
	
	public void saveUserRoles(final User user, final List<Serializable> roleIds)
	{
		final String sql="insert into AUTH_USER_ROLE(AUTH_USER_id,AUTH_ROLE_id) values(?,?)";
		getSession().doWork(new Work()
		{
			
			@Override
			public void execute(Connection connection) throws SQLException
			{
				connection.setAutoCommit(false);
				PreparedStatement stat=connection.prepareStatement(sql);
				for(Serializable id:roleIds)
				{
					stat.setInt(1, user.getId());
					stat.setInt(2,	(int) id);
					stat.addBatch();
				}
				stat.executeBatch();
				connection.commit();
			}
		});
		
	}

	@SuppressWarnings("unchecked")
	public List<Serializable> findUserRoleIds(User user)
	{
		String hql="select ur.role.id from UserRole ur where ur.user.id=?0";
		return getSession().createQuery(hql).setParameter("0", user.getId()).list();
	}
	
	public void updateUserRoles(final User user,List<Serializable> roleIds)
	{
		//判断角色privilegeIds是否为空，如果为空则说明未分配任何权限，则清空数据库该用户所有已有权限关系
		if(CollectionUtils.isEmpty(roleIds))
		{
			unAuthUserRoles(user);
		}
		else
		{
			//找到该角色所有已有权限的id
			List<Serializable> db_roleIds=findUserRoleIds(user);
			//如果在数据库中该角色没有任何权限，页面上分配了权限，则直接保存新分配的所有权限
			if(CollectionUtils.isEmpty(db_roleIds))
			{
				saveUserRoles(user, roleIds);
			}
			else
			{
				//数据库里该用户已经存在的权限不全部包含页面分配的权限，说明有新权限分配，要插入
				if(!db_roleIds.containsAll(roleIds))
				{
					List<Serializable> newRoleIds=new ArrayList<Serializable>();
					for(Serializable roleId:roleIds)
					{
						//如果该分配的权限在数据库中没有则添加
						if(!db_roleIds.contains(roleId))
						{
							newRoleIds.add(roleId);
						}
					}
					//保存新分配的权限
					saveUserRoles(user, newRoleIds);
				}
				
				final StringBuilder sb=new StringBuilder();
				//该用户在页面分配的权限不全部包含数据库中该角色已有权限，即用户在页面上删除了该角色的某些权限
				if(!roleIds.containsAll(db_roleIds))
				{
					sb.append("delete from AUTH_USER_Role where AUTH_USER_id=? and AUTH_ROLE_id in(");
					for(Serializable db_roleId:db_roleIds)
					{
						//数据库中的该角色的权限在页面上没有分配，准备删除该已有权限
						if(!roleIds.contains(db_roleId))
						{
							sb.append(db_roleId).append(",");
						}
					}
					final String sql=sb.deleteCharAt(sb.length()-1).append(")").toString();
					getSession().doWork(new Work()
					{
						
						@Override
						public void execute(Connection connection) throws SQLException
						{
							connection.setAutoCommit(false);
							PreparedStatement stat=connection.prepareStatement(sql);
							stat.setInt(1, user.getId());
							stat.executeUpdate();
							stat.close();
						}
					});
				}
			}
		}
	}
	
	
	public void unAuthUserRoles(User user)
	{
		String hql="delete from UserRole ur where ur.user.id=?";
		batchEntityByHql(hql, user.getId());
		
	}
}
